package com.me.mygdxgame.view;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.utils.Disposable;
import com.me.mygdxgame.assets.Assets;
import com.me.mygdxgame.controller.WorldController;
import com.me.mygdxgame.models.BoxBuilder;
import com.me.mygdxgame.util.Constants;

public class WorldRenderer implements Disposable{
	
	private OrthographicCamera camera;
	public static OrthographicCamera cameraGUI;
	public static Vector2 positionInitCamera;
	private OrthogonalTiledMapRenderer renderer;
	private SpriteBatch batch;
	private WorldController worldController;
	private TiledMap map;
	private Box2DDebugRenderer b2Box2dDebugRenderer;
	private static final boolean DEBUG_DRAW_BOX2D_WORLD = true;
	public static Sprite moveLeft, moveRight, moveJump;
	
	public WorldRenderer(WorldController worldController){
		this.worldController = worldController;
		init();
	}
	
	private void init(){
		
		camera = new OrthographicCamera(Constants.VIEWPORT_WIDTH, Constants.VIEWPORT_HEIGHT);
		camera.position.set(0, 0, 0);
		camera.update();
		
		cameraGUI = new OrthographicCamera(Constants.VIEWPORT_GUI_WIDTH, Constants.VIEWPORT_GUI_HEIGHT);
		cameraGUI.position.set(0, 0, 0);
		cameraGUI.setToOrtho(false);
		cameraGUI.update();
		
		map = new TmxMapLoader().load("map/Level1.tmx");
		

		renderer = new OrthogonalTiledMapRenderer(map, 1);
		batch = (SpriteBatch) renderer.getSpriteBatch();
		positionInitCamera = new Vector2();
		b2Box2dDebugRenderer = new Box2DDebugRenderer();
		
		moveLeft = new Sprite(Assets.leftMove);
		moveLeft.setPosition(30, 10);
		moveLeft.setSize(100, 100);
		
		moveRight = new Sprite(Assets.rightMove);
		moveRight.setPosition(200, 10);
		moveRight.setSize(100, 100);
		
		moveJump = new Sprite(Assets.jumpMove);
//		moveJump.setPosition(Camera. - 180, 30);
		moveJump.setSize(100, 100);
	}
	
	public void render(){
		renderMap();
		renderPlayer();
		renderGui(batch);
	}
	
	private void renderMap() {
		worldController.cameraHelper.applyTo(camera);
//		
		renderer.setView(camera);
		renderer.render();
		batch.setProjectionMatrix(camera.combined);
		batch.enableBlending();
		batch.begin();
		worldController.level.render(batch);
		batch.end();
		
	}
	
	private void renderPlayer(){
		batch.setProjectionMatrix(camera.combined);
		batch.enableBlending();
		batch.begin();
		worldController.player.render(batch);
		batch.end();
		if(DEBUG_DRAW_BOX2D_WORLD){
			b2Box2dDebugRenderer.render(worldController.b2dworld, camera.combined.scl(BoxBuilder.BOX_TO_WORLD));
		}
	}
	
	private void renderGui(SpriteBatch batch){
		batch.setProjectionMatrix(cameraGUI.combined);
		batch.begin();
		renderGuiScore(batch);
		renderGuiExtraLive(batch);
		renderGuiFpsCounter(batch);
		renderGuiController(batch);
		batch.end();
	}
	
	private void renderGuiScore(SpriteBatch batch){
		float x = 10 + 40 + Constants.LIVES_START*40;
		float y = cameraGUI.viewportHeight - 65;
		TextureRegion coin = new TextureRegion(Assets.coins, 0, 0, 40, 40);
		batch.draw(coin, x, y , 20, 20, 40, 40, 1.5f, 1.5f, 0);
		Assets.defaultBig.draw(batch, "" + worldController.score, x + 80, y + 32);
	}
	
	private void renderGuiExtraLive(SpriteBatch batch){
		float x = 10;
		float y = cameraGUI.viewportHeight - 65;
		for(int i = 0; i < Constants.LIVES_START; i++){
			if(worldController.lives <= i)
				batch.setColor(0.5f, 0.5f, 0.5f, 0.5f);
			batch.draw(Assets.live, x + i*45, y, 20, 20, 40, 40, 1, 1, 0);
			batch.setColor(1, 1, 1, 1);
				
		}
		
	}
	
	public void renderGuiFpsCounter(SpriteBatch batch){
		float x = cameraGUI.viewportWidth - 55;
		float y = 15;
		int fps = Gdx.graphics.getFramesPerSecond();
		BitmapFont fpsFont = Assets.defaultNormal;
		if(fps >= 45){
			fpsFont.setColor(0, 1, 0, 1);
		}else if(fps >= 30){
			fpsFont.setColor(1, 1, 0, 1);
		}else {
			fpsFont.setColor(1, 0, 0, 1);
		}
		fpsFont.draw(batch, "FPS: " + fps, x, y);
		fpsFont.setColor(1, 1, 1, 1);
	}
	
	public void renderGuiController(SpriteBatch batch){
		moveLeft.draw(batch);
		moveRight.draw(batch);
		moveJump.draw(batch);
	}

	public void resize(int width, int height){
//		camera.viewportWidth = 18*width/height;
//		camera.viewportHeight = 18;
//		camera.position.set(camera.viewportWidth/2 + 1 , camera.viewportHeight/2, 0);
//		camera.update();
		camera.viewportWidth = (Constants.VIEWPORT_HEIGHT/height)*width;
		camera.position.set(camera.viewportWidth/2 + 40, camera.viewportHeight/2, 0);
		camera.update();
		cameraGUI.viewportHeight = Constants.VIEWPORT_HEIGHT;
		cameraGUI.viewportWidth = (Constants.VIEWPORT_GUI_HEIGHT/
								(float)height)*(float)width;
		cameraGUI.position.set(camera.viewportWidth/2, cameraGUI.viewportHeight/2, 0);
		cameraGUI.update();
		moveJump.setPosition(cameraGUI.viewportWidth - 180, 30);
		positionInitCamera.set(camera.viewportWidth/2 + 40, camera.viewportHeight/2);
		
	}

	@Override
	public void dispose() {
		worldController.b2dworld.dispose();
		renderer.dispose();
	}
	
	

}
